<template>
  <div v-clickoutside="treeHide">
    <div
      class="search-wrap"
      @click.stop="treeShow"
      @mouseenter="inputHoverState = true"
      @mouseleave="inputHoverState = false"
    >
      <span
        @click.stop="clearValue"
        class="el-input__suffix close-icon"
        v-if="
          (inputHoverState || treeShowState) &&
          searchText &&
          !inputProps.readonly &&
          !inputProps.disabled
        "
      >
        <i class="el-icon-circle-close"></i>
      </span>
      <el-input
        size="small"
        v-model="searchText"
        :readonly="true"
        v-bind="inputProps"
      >
        <i
          slot="suffix"
          :class="treeShowState ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"
          v-if="!searchText || (!inputHoverState && !treeShowState)"
        ></i>
      </el-input>
    </div>
    <CommonTree
      class="common-tree"
      v-show="treeShowState"
      ref="commonTree"
      :inputProps="treeInputProps"
      :isSelectDefaultNode="false"
      @node-click="nodeClick"
      :hideMoreBtn="true"
      :defaultExpendMethod="defaultExpendMethod"
      v-bind="treeProps"
    >
      <template v-slot:customNode="scope">
        <slot name="customNode" :data="scope.data" :node="scope.node">
          <span>{{ scope.node.label }}</span>
        </slot>
      </template>
    </CommonTree>
  </div>
</template>
<script>
import clickoutside from "../../../utli/clickoutside";
import CommonTree from "../commonTree/index.vue";
export default {
  components: {
    CommonTree,
  },
  directives: { clickoutside },
  props: {
    value: {},
    initSearchText: { default: "", type: String },
    searchTextFormat: {
      type: Function,
      default: null,
    },
    valueKey: {
      default: "id",
      type: String,
    },
    inputProps: {
      default: () => {
        return {};
      },
      type: Object,
    },
    treeProps: {
      default: () => {
        return {
          props: {
            label: "label",
            children: "children",
          },
        };
      },
      type: Object,
    },
  },
  data() {
    return {
      searchText: "",
      treeShowState: false,
      inputHoverState: false,
      treeInputProps: {
        size: "small",
      },
    };
  },
  watch: {
    value() {
      if (!this.value && this.value !== 0 && this.value !== false) {
        this.searchText = "";
        this.clearCurrentKey();
      }
    },
  },
  created() {
    this.searchText = this.initSearchText || "";
  },
  methods: {
    clearCurrentKey() {
      this.$refs.commonTree.setCurrentKey(null);
    },
    defaultExpendMethod(treeData) {
      let defaultExpandedKeys = [];
      treeData.forEach((node) => {
        defaultExpandedKeys.push(node.id);
      });
      return defaultExpandedKeys;
    },
    treeStateChange(flag) {
      this.treeShowState = flag;
      this.$emit("stateChange", flag);
      if (flag) {
        this.changeTreeStyle();
      }
    },
    getPropertyValue(dom, key) {
      return getComputedStyle(dom, null).getPropertyValue(key);
    },
    getFlag(node = this.$el) {
      let parentElement = node.parentElement;
      let flag =
        this.getPropertyValue(parentElement, "transform") !== "none" ||
        this.getPropertyValue(parentElement, "filter") !== "none" ||
        this.getPropertyValue(parentElement, "perspective") !== "none";

      if (!flag && parentElement && parentElement.parentElement) {
        return this.getFlag(parentElement);
      }
      return flag;
    },
    changeTreeStyle() {
      let flag = this.getFlag();
      let searchBox = this.$el.querySelector(".search-wrap");
      let box = this.$el.querySelector(".common-tree");
      let widthNumber = searchBox.offsetWidth;
      box.style.width = widthNumber + "px";
      if (flag) {
        box.style.left = "auto";
        box.style.top = "auto";
        return;
      }
      let bodyHeight = document.body.offsetHeight;

      let topNumber = searchBox.getBoundingClientRect().top;
      let leftNumber = searchBox.getBoundingClientRect().left;

      let searchWrapHeight =
        this.$el.querySelector(".search-wrap").offsetHeight;
      let bottomCount = bodyHeight - topNumber - searchWrapHeight;

      let heightNumber = searchBox.offsetHeight;

      box.style.left = leftNumber + "px";
      if (bottomCount < 340) {
        box.style.top = topNumber - 300 - 4 + "px";
      } else {
        box.style.top = topNumber + heightNumber + 8 + "px";
      }
    },
    treeShow() {
      if (this.inputProps.disabled) {
        return;
      }
      this.treeStateChange(true);
    },
    treeHide() {
      this.treeStateChange(false);
    },
    clearValue() {
      this.searchText = "";
      this.$emit("update:value", "");
      this.treeHide();
      this.$emit("clear");
    },
    setValue(data = {}) {
      if (!this.searchTextFormat) {
        this.searchText = data[this.treeProps.props.label];
      } else {
        this.searchText = this.searchTextFormat(data);
      }
      this.$emit("update:value", data[this.valueKey]);
      this.treeHide();
    },
    nodeClick(data) {
      this.setValue(data);
      this.$emit("nodeClick", data);
    },
  },
};
</script>
<style scoped>
.common-tree-search {
  position: relative;
}
.common-tree-search .search-wrap {
  position: relative;
  margin-bottom: 8px;
}
.common-tree-search .search-wrap .close-icon {
  z-index: 2;
  display: flex;
  align-items: center;
  cursor: pointer;
  pointer-events: auto;
  width: 25px;
  justify-content: center;
}
.common-tree-search .search-wrap .el-input ::v-deep .el-input__suffix,
.el-input__suffix-inner {
  display: flex;
  align-items: center;
  width: 25px;
  justify-content: center;
}
.common-tree {
  position: fixed;
  height: 300px;
  z-index: 9;
  border: 1px solid #e0e0e0;
  padding: 8px;
  background-color: #fff;
  border-radius: 4px;
}
.common-tree-search .common-tree ::v-deep .head-title {
  display: none;
}
.common-tree-search .common-tree .el-tree .el-tree-node__content {
  height: 32px;
  line-height: 32px;
}
</style>
